package org.komarichin.google.search.deserializers;

import com.google.gson.*;
import org.komarichin.google.search.*;

import java.lang.reflect.Type;

/**
 * <p>
 * &nbsp;
 * </p>
 * User: Michael Komarichin
 * Date: Jan 28, 2010
 * Time: 11:52:55 PM
 */
public class ResponseDataDeserializer implements JsonDeserializer<ResponseData> {

    private static final String RESPONSE_DATAILS = "responseDetails";
    private static final String RESPONSE_STATUS = "responseStatus";
    private static final String RESPONSE_DATA = "responseData";
    private static final String RESULTS = "results";
    private static final String CACHE_URL = "cacheUrl";
    private static final String CONTENT = "content";
    private static final String G_SEARCH_RESULT_CLASS = "GsearchResultClass";
    private static final String TITLE = "title";
    private static final String TITLE_NO_FORMATTING = "titleNoFormatting";
    private static final String URL = "url";
    private static final String UNESCAPE_URL = "unescapeUrl";
    private static final String VISIBLE_URL = "visibleUrl";
    private static final String CURSOR = "cursor";
    private static final String LABEL = "label";
    private static final String START = "start";
    private static final String PAGES = "pages";
    private static final String ESTIMATED_RESULT_COUNT = "estimatedResultCount";
    private static final String CURRENT_PAGE_INDEX = "currentPageIndex";
    private static final String MORE_RESULT_URL = "moreResultsUrl";


    @Override
    public ResponseData deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        ResponseData result = new ResponseData();
        fillResponseDate(result, jsonElement.getAsJsonObject());
        return result;
    }

    private void fillResponseDate(ResponseData data, JsonObject json) {
        if (!json.get(RESPONSE_DATAILS).isJsonNull()) {
            data.setResponseDetails(getStringValue(json.get(RESPONSE_DATAILS)));
        }
        if (!json.get(RESPONSE_STATUS).isJsonNull()) {
            data.setResponseStatus(json.get(RESPONSE_STATUS).getAsInt());
        }
        Result res = new Result();
        data.setResults(res);
        fillResults(res, json.get(RESPONSE_DATA).getAsJsonObject());
    }

    private void fillResults(Result res, JsonObject json) {
        if (!json.get(RESULTS).isJsonNull()) {
            for (JsonElement el : json.get(RESULTS).getAsJsonArray()) {
                GwebSearch g = new GwebSearch();
                g.setCacheUrl(getStringValue(el.getAsJsonObject().get(CACHE_URL)));
                g.setContent(getStringValue(el.getAsJsonObject().get(CONTENT)));
                g.setGsearchResultClass(getStringValue(el.getAsJsonObject().get(G_SEARCH_RESULT_CLASS)));
                g.setTitle(getStringValue(el.getAsJsonObject().get(TITLE)));
                g.setTitleNoFormatting(getStringValue(el.getAsJsonObject().get(TITLE_NO_FORMATTING)));
                g.setUnescapedUrl(getStringValue(el.getAsJsonObject().get(UNESCAPE_URL)));
                g.setUrl(getStringValue(el.getAsJsonObject().get(URL)));
                g.setVisibleUrl(getStringValue(el.getAsJsonObject().get(VISIBLE_URL)));
                res.getGwebSearch().add(g);
            }
        }
        if (json.get(CURSOR) != null && json.get(CURSOR).isJsonNull()) {
            Cursor cur = new Cursor();
            res.setCursor(cur);
            fillCursor(cur, json.get(CURSOR).getAsJsonObject());
        }
    }

    private String getStringValue(JsonElement el) {
        return el != null && !el.isJsonNull() ? el.getAsString() : null;

    }

    private void fillCursor(Cursor cur, JsonObject json) {
            cur.setEstimatedResultCount(getStringValue(json.get(ESTIMATED_RESULT_COUNT)));
        if (json.get(CURRENT_PAGE_INDEX) != null && !json.get(CURRENT_PAGE_INDEX).isJsonNull()) {
            cur.setCurrentPageIndex(json.get(CURRENT_PAGE_INDEX).getAsLong());
        }
            cur.setMoreResultsUrl(getStringValue(json.get(MORE_RESULT_URL)));
        if (json.get(PAGES) != null && !json.get(PAGES).isJsonNull()) {
            for (JsonElement el : json.get(PAGES).getAsJsonArray()) {
                Pages p = new Pages();
                p.setStart(el.getAsJsonObject().get(START).getAsString());
                p.setLabel(el.getAsJsonObject().get(LABEL).getAsLong());
                cur.getPages().add(p);
            }
        }
    }

}
